home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / UI / StdDispM.cpp < prev    next >
Encoding:
Text File  |  1997-02-13  |  52.8 KB  |  1,686 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        StdDispM.cpp
  3.  
  4.     Contains:    Implementation of standard dispatch module for Macintosh events
  5.  
  6.     Owned by:    Chris Linn
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <10>      11/27/96    CSL        1400043: Even more agressive orphan
  13.                                     mouse-up fixes
  14.          <9>      10/23/96    DH        1378925: Sniff the event queue to see if 
  15.                                      mouse-up was consumed during mouse-down 
  16.                                      handling (for CSL).
  17.          <8>     10/4/96    CSL        1334277: Show AboutBox for users;  1377685:
  18.                                     Suppress orphan mouse-up after window grow
  19.          <7>     9/18/96    CSL        1373276: update cache of arbitrator, etc.,
  20.                                     on every Dispatch so patching will work.
  21.                                     1379322: fix refcount bug in propogated
  22.                                     events.  1378925: don't deliver orphan
  23.                                     mouse-up events.
  24.          <6>     8/14/96    CSL        1378142: Mouse-up causes crash if mouse-
  25.                                     down facet is invalid
  26.          <5>     6/22/96    EL        1344140: make sure menu is unhighlighted if
  27.                                     error is thrown.
  28.          <4>     6/21/96    CSL        1330394: Mouse-up doesn't get to frame
  29.                                     embedded in selection. 1330894: Mouse
  30.                                     events outside active shape of root frame
  31.                                     are not delivered. 1337817: modified mouse
  32.                                     events not delivered to floating windows.
  33.          <3>     6/14/96    eeh        1358680: send menuevent when F-[1…4]
  34.                                     pressed
  35.          <2>     6/12/96    eeh        1308137: send fake menuevent when
  36.                                     command-key is invalid
  37.         <48>    10/10/95    DM        1277216: GM:API: Dont return ODPoint from
  38.                                     GetWindowPoint()
  39.         <47>    10/10/95    RR        1289924    Now get kODEvtMouseUpEmbedded with
  40.                                     bundled embedded frames
  41.         <46>     9/21/95    RR        #1286167 Suppress mouse up after bg
  42.                                     mousedown. Renamed fInvalidClick to
  43.                                     fSuppressMouseUp
  44.         <45>     9/13/95    DM        1277216 GM:API return no ODPoints nor
  45.                                     ODPolygons
  46.         <44>     9/12/95    DM        1280020 FB1 part trans dlg mem leaks
  47.         <43>     9/12/95    JBS        1283337 use TempOD<Object>s to make
  48.                                     refcounting exception safe
  49.         <42>     9/12/95    RR        Changed some somPrintfs
  50.         <41>     8/29/95    DM        1221778, 1276165: [ShowLinkUpdateAlert]
  51.                                     call LinkMgr SuspendResume()
  52.         <40>     8/29/95    RR        #1267251 handle synthesized activate events
  53.         <39>     7/26/95    DM        #1270320: Memory leak fixes.
  54.         <38>     6/28/95    RR        #1242642. Ref counting fixes
  55.         <37>     6/28/95    JBS        1262900 if click in icon view root frame,
  56.                                     pass to shell instead of Redispatch
  57.         <36>     6/26/95    TÇ        1242642 BB:Fix refcounting bugs
  58.         <35>     6/25/95    TÇ        1242642 BB: Turn on ODDebug warning if
  59.                                     refcount is wrong in
  60.                                     ODRefCntObjectsomUninit.
  61.         <34>     6/20/95    JBS        1257315 change Facet::AcquireWindow to
  62.                                     GetWindow
  63.         <33>     6/15/95    RR        #1256879 Get->AcquireCurrentMenuBar
  64.         <32>     5/31/95    RR        #1251403 Release after AcquirePart
  65.         <31>     5/26/95    RR        #1251403: Multithreading naming support
  66.         <30>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  67.         <29>     5/17/95    RR        #1250135/1250137/1250143 Getters increment
  68.                                     refcount
  69.         <28>     5/15/95    RR        # 1249142 Added checks for NULL to
  70.                                     PropagateTheEvent
  71.         <27>     5/10/95    RR        # 1242893, 1245692 Fixed Mouse up
  72.                                     dispatching
  73.         <26>     5/10/95    JBS        1241913 ODPart::AdjustBorderShape is not
  74.                                     called with null shape; 1224727 Facet
  75.                                     hit-testing calls should take point param
  76.                                     in frame coords
  77.         <25>      5/2/95    RR        # 1226050 Added fLastBorderFrame.
  78.         <24>     4/28/95    RR        1211085 Remove 5$ comments
  79.         <23>      4/6/95    RR        #1220104 Use of ODObjectsAreEqual, #1211085
  80.                                     Remove 5$ comments
  81.         <22>      4/4/95    RR        1220104 Use ODObjectsAreEqual, 1227750
  82.                                     local coords for mouseUp
  83.         <21>     3/13/95    NP        1221979: Remove incorrect comment.
  84.         <20>     3/10/95    RR        # 1199122 Dispatch Null Menu Events
  85.         <19>      3/7/95    RR        # 122649 WindowToLocal on eventInfo->where
  86.         <18>      3/1/95    RR        # 1224776 Disabled dispatching of activate
  87.                                     events, since it interferes with floating
  88.                                     window strategy.
  89.         <17>     2/28/95    jpa        Removed a bit o' test code accidentally
  90.                                     left in [1220704]
  91.         <16>     2/24/95    jpa        Dispatch kODEvtBGMouseDown &
  92.                                     kODEvtBGMouseDownEmbedded [1220704]
  93.         <15>     2/22/95    RR        # 1213850 Dispatch menu events to root part
  94.                                     of active window if not handled by menu
  95.                                     focus
  96.         <14>     2/20/95    TÇ        #1221861 BB: Incomplete AOCE support needs
  97.                                     to be removed from OpenDoc
  98.         <13>     1/31/95    RR        # 1162080 delete facet iterator in
  99.                                     GetActiveFacetWithBorderUnderPoint
  100.         <12>     1/13/95    RR        Added eventInfo to event handling methods.
  101.                                     Remove calls to HandleEventInEmbedded
  102.         <11>     11/1/94    RR        #1196756 Don't call DialogSelect for
  103.                                     updates and activates
  104.         <10>    10/27/94    eeh        #1191434 for RR: handle dlogs with the
  105.                                     modal focus correctly
  106.          <9>    10/27/94    RR        # 1191434 Check for ViewAsIcon etc in
  107.                                     DispatchToFacetUnderPoint. No longer handle
  108.                                     dialog updates and activates
  109.          <8>    10/21/94    NP        1187682: TSM support.
  110.          <7>    10/18/94    RR        Check for null containing facet in
  111.                                     DispatchToFacetUnderPoint
  112.          <6>     9/30/94    RR        #1188888, #1171182 For mouse clicks,
  113.                                     respect icon views, selected and dragging
  114.                                     states.
  115.          <5>     9/20/94    RR        #1167854. Rewrote DispatchKeyDown so that
  116.                                     unmatched command keys are passed to part
  117.                                     as a keystroke
  118.          <4>      9/6/94    RR        #1183392. Call HandleEventInEmbedded where
  119.                                     appropriate
  120.          <3>     8/10/94    JBS        1179919: coordinate system bias changes
  121.          <2>     7/26/94    eeh        ODQDPoint->Point
  122.          <1>     6/24/94    RR        first checked in
  123.          <7>      5/4/94    SS        #1160449: fixes for ModalFocus dialogs
  124.          <6>      4/8/94    RR        #1144767
  125.          <5>      4/1/94    TÇ        #1154941: Get OpenDoc source to actually
  126.                                     compile for PowerPC
  127.          <4>     3/28/94    CG        1153547: Renamed XMPSessn.h to XMPSessM.h
  128.          <3>     3/16/94    RR        #1151144. Made global functions static
  129.          <2>     2/16/94    JA        Include new AltPoint.h.
  130.         <38>      2/7/94    NP        Tiger Team doings.
  131.         <37>      2/7/94    NP        Tiger Team doings.
  132.         <36>     1/21/94    RR        Restored Dispatch() signature
  133.         <35>     1/20/94    RR        Handle AOCE Mailer events
  134.         <34>     1/18/94    RR        Use scrolling focus for pageUp etc., add
  135.                                     propagation
  136.         <33>     1/15/94    RR        WinState.h->WinStat.h,
  137.                                     Dispatch.h->Disptch.h
  138.         <32>     1/15/94    RR        Updated DispatchMenuEvent (command no. is
  139.                                     no longer in event)
  140.         <31>     1/14/94    RR        Shift-click in active border beeps
  141.         <30>     1/11/94    TÇ        Init... changes
  142.         <29>     1/10/94    RR        Added HiliteMenu calls
  143.         <28>    12/20/93    RR        New init strategy
  144.         <27>    12/16/93    RR        Various methods respect modal focus. Update
  145.                                     and activate events in dialogs are handled.
  146.                                     DispatchToFacetUnderPoint became a member
  147.                                     function.
  148.         <26>    12/15/93    JBS        activeShape & window now in facet not frame
  149.         <25>    12/13/93    RR        Remove warning.
  150.         <24>     12/6/93    RR        Call WindowState->SuspendResume
  151.         <23>     12/3/93    CC        SuspendResume: Moved call to
  152.                                     ExportClipboard() into the shell; no longer
  153.                                     modifies its event parameter so shell can
  154.                                     post-process the event.
  155.         <22>     12/2/93    CC        SuspendResume: Catch errors thrown by
  156.                                     ExportClipboard().
  157.         <21>     12/2/93    RR        Fixed some bugs in handling of mouse events
  158.         <20>    11/24/93    CC        Call ExportClipboard() on suspend events
  159.         <19>    11/19/93    RR        Correctly set "handled"
  160.         <18>    11/19/93    RR        Use correct event codes. Handle command
  161.                                     keys. Dispatch mouse downs in title bar to
  162.                                     root part.
  163.         <17>    11/18/93    JBS        use activeFrame->AcquireWindow()
  164.         <16>    11/16/93    RR        Central Casting for CFront
  165.         <15>    11/16/93    RR        Quick hack in MouseDownInContent until
  166.                                     Frame/Facet/Active Border is sorted out
  167.         <14>    11/16/93    RR        Shell now constructs menu events. Also
  168.                                     update for cursor-tracking and idling
  169.         <13>    11/12/93    JBS        use Facets
  170.         <12>    10/27/93    RR        Use Window::AcquireFrameUnderPoint instead of
  171.                                     local routine.
  172.         <11>    10/12/93    PH        Do some cleanup for VodooMonkey
  173.         <10>     10/8/93    RR        Use IsXMPWindow
  174.          <9>     10/6/93    JA        Use new fixed-point XMPPoint.
  175.          <8>     10/1/93    RR        Ignore 0 result of MenuSelect()
  176.          <7>     9/16/93    RR        Menu event uses command number
  177.          <6>     9/15/93    RR        Use command number in menu event (currently
  178.                                     commented out)
  179.          <5>      9/3/93    JBS        updated to use new Layout class
  180.          <4>     8/24/93    TÇ        commented out ifdef PROTOTYPEBUILD so
  181.                                     implementation could use hit detection code
  182.                                     from prototype
  183.          <3>     8/24/93    RR        Got rid of some CFront warnings
  184.          <2>     8/11/93    RR        Included hit detection code from prototype,
  185.                                     for now
  186.          <1>     8/10/93    RCR        first checked in
  187.  
  188.     To Do:
  189.     In Progress:
  190.  
  191. */
  192.  
  193. #ifndef _ALTPOINT_
  194. #include "AltPoint.h"            // Use C++ savvy ODPoint and ODRect
  195. #endif
  196.  
  197.  
  198. #ifndef _STDDISPM_
  199. #include "StdDispM.h"
  200. #endif
  201.  
  202. #ifndef _TEMPOBJ_
  203. #include <TempObj.h>
  204. #endif
  205.  
  206. #ifndef _ODSESSN_
  207. #include "ODSessn.xh"
  208. #endif
  209.  
  210. #ifndef SOM_ODDispatcher_xh
  211. #include "Disptch.xh"
  212. #endif
  213.  
  214. #ifndef SOM_ODWindow_xh
  215. #include "Window.xh"
  216. #endif
  217.  
  218. #ifndef SOM_ODFacet_xh
  219. #include "Facet.xh"
  220. #endif
  221.  
  222. #ifndef SOM_ODWindowState_xh
  223. #include "WinStat.xh"
  224. #endif
  225.  
  226. #ifndef SOM_ODMenuBar_xh
  227. #include "MenuBar.xh"
  228. #endif
  229.  
  230. #ifndef SOM_Module_OpenDoc_Commands_defined
  231. #include "CmdDefs.xh"
  232. #endif
  233.  
  234. #ifndef SOM_LinkMgr_xh
  235. #include <LinkMgr.xh>
  236. #endif
  237.  
  238. #ifndef SOM_ODArbitrator_xh
  239. #include "Arbitrat.xh"
  240. #endif
  241.  
  242. #ifndef SOM_ODPart_xh
  243. #include "Part.xh"
  244. #endif
  245.  
  246. #ifndef SOM_Module_OpenDoc_Foci_defined
  247. #include "Foci.xh"
  248. #endif
  249.  
  250. #ifndef SOM_ODFrame_xh
  251. #include "Frame.xh"
  252. #endif
  253.  
  254. #ifndef SOM_ODFrameFacetIterator_xh
  255. #include "FrFaItr.xh"
  256. #endif
  257.  
  258. #ifndef SOM_ODFacetIterator_xh
  259. #include "FacetItr.xh"
  260. #endif
  261.  
  262. #ifndef _DSPUTILM_
  263. #include "DspUtilM.h"
  264. #endif
  265.  
  266. #ifndef _USERSRCM_
  267. #include "UseRsrcM.h"
  268. #endif
  269.  
  270. #ifndef _UIDEFS_
  271. #include "UIDefs.h"
  272. #endif
  273.  
  274. #ifndef _ITEXT_
  275. #include "IText.h"
  276. #endif
  277.  
  278. #ifndef _ABOUTBOX_
  279. #include "AboutBox.h"
  280. #endif
  281.  
  282. #ifndef __EPPC__
  283. #include <EPPC.h>
  284. #endif
  285.  
  286. #ifndef __MENUS__
  287. #include <Menus.h>
  288. #endif
  289.  
  290. #ifndef __DIALOGS__
  291. #include <Dialogs.h>
  292. #endif
  293.  
  294. #ifndef __TOOLUTILS__
  295. #include <ToolUtils.h>
  296. #endif
  297.  
  298. #ifndef __TEXTSERVICES_
  299. #include <TextServices.h>
  300. #endif
  301.  
  302. #pragma segment ODStdDispatchModule
  303.  
  304. #define ODDebugMenuEvents 0
  305. #define ODDebugLayerEvents 0
  306. #define ODDebugTitleBarEvents 0
  307. #define ODLogEvents 0
  308.  
  309. //=====================================================================================
  310. // Types
  311. //=====================================================================================
  312.  
  313. typedef enum { kNotAnFKey, kDisabledFKey, kEnabledFKey } FKeyResult;
  314.  
  315. //=====================================================================================
  316. // Constants
  317. //=====================================================================================
  318.  
  319. const short     kSuspendResumeMessage = 0x01;    // High byte suspend/resume event 
  320. const short     kClipConvertMask      = 0x02;    // Bit of message field clip conversion
  321. const short     kResumeMask           = 0x01;    // Resume vs. suspend mask
  322. const short     kMouseMovedMessage    = 0xFA;    // High byte mouse-moved event message
  323.  
  324. //----------------------------------------------------------------------------------------
  325. // Enumeration for ASCII Character Constants
  326. //----------------------------------------------------------------------------------------
  327.  
  328. enum EAsciiControlCode {
  329.     chBackspace = 8,                    // ASCII code for Backspace character  
  330.     chClear = 27,                        // ASCII code for Clear key (aka ESC)  
  331.     chDown = 31,                        // ASCII code for down arrow  
  332.     chEnd = 4,                            // ASCII code for the End key  
  333.     chEnter = 3,                        // ASCII code for Enter character  
  334.     chEscape = 27,                        // ASCII code for Escape (aka Clear) key  
  335.     chFunction = 16,                    // ASCII code for any function key  
  336.     chFwdDelete = 127,                    // ASCII code for forward delete  
  337.     chHelp = 5,                            // ASCII code for Help key  
  338.     chHome = 1,                            // ASCII code for the Home key  
  339.     chLeft = 28,                        // ASCII code for left arrow  
  340.     chPageDown = 12,                    // ASCII code for Page Down key  
  341.     chPageUp = 11,                        // ASCII code for Page Up key  
  342.     chReturn = 13,                        // ASCII code for Return character  
  343.     chRight = 29,                        // ASCII code for right arrow  
  344.     chSpace = 32,                        // ASCII code for Space character  
  345.     chTab = 9,                            // ASCII code for Tab character  
  346.     chUp = 30                            // ASCII code for up arrow
  347. };
  348.  
  349.  
  350. //----------------------------------------------------------------------------------------
  351. // Enumeration for Virtual Key Code Constants
  352. //----------------------------------------------------------------------------------------
  353.  
  354. enum EVirtualKeyCode {
  355.     kClearVirtualCode = 71,                // Clear key virtual code  
  356.     kEscapeVirtualCode = 53,            // Escape key virtual code  
  357.     kF10VirtualCode = 109,                // F10 virtual key code  
  358.     kF11VirtualCode = 103,                // F11 virtual key code  
  359.     kF12VirtualCode = 111,                // F12 virtual key code  
  360.     kF13VirtualCode = 105,                // F13 virtual key code  
  361.     kF14VirtualCode = 107,                // F14 virtual key code  
  362.     kF15VirtualCode = 113,                // F15 virtual key code  
  363.     kF1VirtualCode = 122,                // F1 virtual key code  
  364.     kF2VirtualCode = 120,                // F2 virtual key code  
  365.     kF3VirtualCode = 99,                // F3 virtual key code  
  366.     kF4VirtualCode = 118,                // F4 virtual key code  
  367.     kF5VirtualCode = 96,                // F5 virtual key code  
  368.     kF6VirtualCode = 97,                // F6 virtual key code  
  369.     kF7VirtualCode = 98,                // F7 virtual key code  
  370.     kF8VirtualCode = 100,                // F8 virtual key code  
  371.     kF9VirtualCode = 101,                // F9 virtual key code  
  372.     kFwdDelVirtualCode = 117            // Forward Delete virtual code
  373. };
  374.  
  375.  
  376. //=====================================================================================
  377. // Static Utilties
  378. //=====================================================================================
  379. #pragma mark ---------- Static Utilities ----------
  380.  
  381. static ODBoolean IsContained(Environment* ev, ODFrame* frame, ODFrame* container)
  382. {
  383.     if ( (frame == kODNULL) || (container == kODNULL))
  384.         return kODFalse;
  385.     if (ODObjectsAreEqual(ev, frame, container))
  386.         return kODTrue;
  387.         
  388.     ODFrame* tempFrame = frame;
  389.     ODFrame* tempContainer = kODNULL;
  390.     tempFrame->Acquire(ev);    // -- TÇ added
  391.     while (tempFrame != kODNULL)
  392.     {
  393.         tempContainer = tempFrame->AcquireContainingFrame(ev);
  394.         tempFrame->Release(ev); // -- TÇ added
  395.         if (ODObjectsAreEqual(ev, tempContainer, container))
  396.         {
  397.             tempContainer->Release(ev); // -- TÇ added
  398.             return kODTrue;
  399.         }
  400.         tempFrame = tempContainer;        
  401.     }
  402.     return kODFalse;
  403. }
  404.  
  405. static ODFacet* GetActiveFacet(Environment* ev, ODFrame* frame, ODWindow* window, ODPoint& windowPoint)
  406. // Could be a frame method
  407. // Return the facet of "frame" which contains the point, or kODNULL
  408. {
  409.     ODFacet* foundFacet = kODNULL;
  410.     ODPoint framePoint;
  411.  
  412.     if ( frame && window )
  413.     {
  414.         ODFrameFacetIterator* iter = frame->CreateFacetIterator(ev);
  415.  
  416.         for (ODFacet* facet = iter->First(ev);
  417.                 iter->IsNotComplete(ev);
  418.                 facet = iter->Next(ev))
  419.         {
  420.             {
  421.                 // get windowPoint in frame coords for hit-testing
  422.                 TempODTransform winToFrame = facet->AcquireWindowFrameTransform(ev, kODNULL);
  423.                 framePoint = windowPoint;
  424.                 winToFrame->InvertPoint(ev, &framePoint);
  425.             }
  426.             if (ODObjectsAreEqual(ev, facet->GetWindow(ev), window)
  427.                 && facet->ContainsPoint(ev, &framePoint, kODNULL) )
  428.             {
  429.                 foundFacet = facet;
  430.                 break;
  431.             }
  432.         }
  433.  
  434.         delete iter;
  435.     }
  436.     return foundFacet;
  437. }
  438.  
  439. static ODFacet* GetFirstFacetUnderPoint(Environment* ev, ODWindow* window, ODFacet* root, ODPoint& windowPoint)
  440. {
  441. // returns NULL, root or an embedded facet of root
  442.  
  443.     ODFacet* foundFacet = kODNULL;
  444.     ODPoint framePoint;
  445.  
  446.     if (window && root && (ODObjectsAreEqual(ev, root->GetWindow(ev),window)))
  447.     {
  448.         ODFacetIterator* t = root->CreateFacetIterator(ev, kODTopDown, kODFrontToBack);
  449.         TempODObject tempIterator(t); // DMc - ensure deletion despite return/exceptions
  450.  
  451.         ODFacet* facet = t->First(ev);
  452.         
  453.         // get windowPoint in frame coords for hit-testing
  454.         {
  455.             TempODTransform winToFrame = facet->AcquireWindowFrameTransform(ev, kODNULL);
  456.             framePoint = windowPoint;
  457.             winToFrame->InvertPoint(ev, &framePoint);
  458.         }
  459.  
  460.         if ( !facet->ContainsPoint(ev, &framePoint, kODNULL) )
  461.             return kODNULL;
  462.  
  463.         for ( facet = t->Next(ev);
  464.                 t->IsNotComplete(ev);
  465.                 facet = t->Next(ev) )
  466.         {
  467.             // get windowPoint in frame coords for hit-testing
  468.             {
  469.                 TempODTransform winToFrame = facet->AcquireWindowFrameTransform(ev, kODNULL);
  470.                 framePoint = windowPoint;
  471.                 winToFrame->InvertPoint(ev, &framePoint);
  472.             }
  473.             if (facet->ContainsPoint(ev, &framePoint, kODNULL))
  474.             {
  475.                 foundFacet = facet;
  476.                 break;
  477.             }
  478.             else
  479.                 t->SkipChildren(ev); 
  480.         }
  481.         // delete t; // now deleted by TempODObject
  482.     }
  483.     if ( foundFacet )
  484.         return foundFacet;
  485.     else
  486.         return root;
  487. }
  488.  
  489. //-------------------------------------------------------------------------------------
  490. // IsValidFacet
  491. //
  492. // Returns true if the candidate address points to an ODFacet object.
  493. //-------------------------------------------------------------------------------------
  494.  
  495. static ODBoolean IsValidFacet( ODFacet* candidateFacet )
  496. {
  497.     ODBoolean isValid = kODFalse;
  498.  
  499.     if ( candidateFacet != kODNULL )
  500.     {
  501.         if ( somIsObj ( candidateFacet ))
  502.         {
  503.             somId facetSomID = somIdFromString( (corbastring)"ODFacet");
  504.             SOMClassMgr* classMgr = somGetClassManagerReference();
  505.             SOMClass* facetClass = classMgr->somClassFromId( facetSomID );
  506.             somReleaseClassManagerReference( classMgr );
  507.             SOMFree( facetSomID );
  508.  
  509.             isValid = ( facetClass != kODNULL && candidateFacet->somIsA( facetClass ));
  510.         }
  511.     }
  512.     return isValid;
  513. }
  514.  
  515. static ODBoolean SetupAboutOpenDocMenuText( Environment* ev, ODWindowState* windowState )
  516. {
  517.     ODBoolean wasSuccessful = kODFalse;
  518.     ODIText* string = kODNULL;
  519.  
  520.     TRY
  521.  
  522.         CUsingLibraryResources r;
  523.         Handle strHandle = ::Get1Resource( 'STR ', kODAboutOpenDocStrID );
  524.         if ( strHandle != kODNULL )
  525.         {
  526.             ODScriptCode script = FontToScript( GetSysFont());
  527.             ODIText* string = CreateITextPString( script,
  528.                                  GetScriptVariable( script, smScriptLang), 
  529.                                  (StringPtr)*strHandle); 
  530.             TempODMenuBar menuBar = windowState->AcquireCurrentMenuBar( ev );
  531.             menuBar->SetItemString( ev, kODCommandAbout, string );
  532.             DisposeIText( string );
  533.             string = kODNULL;
  534.             wasSuccessful = kODTrue;
  535.         }
  536.     CATCH_ALL
  537.         DisposeIText( string );
  538.     ENDTRY
  539.  
  540.     return wasSuccessful;
  541. }
  542.  
  543. static ODBoolean IsAboutOpenDocEvent( Environment* ev, 
  544.                     ODWindowState* windowState, long menuResult )
  545. {
  546.     ODBoolean wasHandled = kODFalse;
  547.  
  548.     TRY    
  549.         short menu = HiWord( menuResult );
  550.         short item = LoWord( menuResult );
  551.         TempODMenuBar menuBar = windowState->AcquireCurrentMenuBar( ev );
  552.         ODCommandID command = menuBar ? menuBar->GetCommand(ev, menu, item) : 0;                
  553.         if (command == kODCommandAbout)
  554.         {
  555.             ShowAboutBox( ev, windowState );
  556.             wasHandled = kODTrue;
  557.         }
  558.         
  559.     CATCH_ALL
  560.         ;    // Suppress exceptions
  561.     ENDTRY
  562.  
  563.     return wasHandled;
  564. }
  565.  
  566. static void FakeMenuEvent( Environment* ev, ODDispatcher* disp )
  567. {
  568.     ODEventData fakeEvent;
  569.     fakeEvent.what = kODEvtMenu;
  570.     fakeEvent.message = 0L;        // are we sure parts will do the right thing?
  571.     (void)disp->Redispatch( ev, &fakeEvent, kODNULL );
  572. }
  573.  
  574. static FKeyResult ConvertKeyToFKeyMenuEvent( Environment* ev, ODEventData* theEvent,
  575.         ODWindowState* ws )
  576. {
  577.     FKeyResult result = kNotAnFKey;
  578.     char key = (char) (theEvent->message & charCodeMask) ;
  579.     if ( key == 0x10 )            // function key
  580.     {
  581.         char keyCode = (theEvent->message & keyCodeMask) >> 8;
  582.         ODCommandID commandID;
  583.         switch( keyCode )
  584.         {
  585.             case 0x7A:
  586.                 commandID = kODCommandUndo; break;
  587.             case 0x78:
  588.                 commandID = kODCommandCut; break;
  589.             case 0x63:
  590.                 commandID = kODCommandCopy; break;
  591.             case 0x76:
  592.                 commandID = kODCommandPaste; break;
  593.             default:
  594.                 commandID = 0;
  595.         }
  596.         if ( commandID != 0 )
  597.         {
  598.             TRY
  599.                 ODMenuID menu;
  600.                 ODMenuItemID item;
  601.                 TempODMenuBar menuBar = ws->AcquireCurrentMenuBar(ev);
  602.                 menuBar->GetMenuAndItem( ev, commandID, &menu, &item );    // can throw
  603.                 ODPlatformMenu macMenu = menuBar->GetMenu( ev, menu );        // can throw
  604.                 long enableFlags = (*macMenu)->enableFlags;
  605.                 long mask = 0x00000001 | (0x00000001 << item);
  606.                 enableFlags = enableFlags & mask;
  607.                 if ( enableFlags == mask )        // are *both* bits set?
  608.                 {
  609.                     theEvent->message = menu << 16 | item;
  610.                     result = kEnabledFKey;
  611.                 }
  612.                 else
  613.                     result = kDisabledFKey;
  614.             CATCH_ALL
  615.                 // don't reraise!
  616.             ENDTRY
  617.         }
  618.     }
  619.     return result;
  620. }
  621.  
  622. //=====================================================================================
  623. // Class MacDispatchModule
  624. //=====================================================================================
  625. #pragma mark ---------- Class MacDispatchModule ----------
  626.  
  627. //-------------------------------------------------------------------------------------
  628. // MacDispatchModule::MacDispatchModule
  629. //
  630. // Description
  631. //-------------------------------------------------------------------------------------
  632.  
  633. MacDispatchModule::MacDispatchModule()
  634. {
  635.     fArbitrator = kODNULL;
  636.     fWindowState = kODNULL;
  637.  
  638.     fMouseDownFacet = kODNULL;
  639.     fEmbeddedFacet = kODNULL;
  640.     fSuppressMouseUp = kODFalse;
  641.     fMouseButtonIsDown = kODFalse;
  642. }
  643.  
  644. //-------------------------------------------------------------------------------------
  645. // MacDispatchModule::~MacDispatchModule
  646. //
  647. // Description
  648. //-------------------------------------------------------------------------------------
  649.  
  650. MacDispatchModule::~MacDispatchModule()
  651. {
  652. }
  653.  
  654. //-------------------------------------------------------------------------------------
  655. // MacDispatchModule::InitStandardDispatchModule
  656. //
  657. // Description
  658. //-------------------------------------------------------------------------------------
  659.  
  660. void MacDispatchModule::InitMacDispatchModule(Environment* ev, ODSession* session)
  661. {    
  662.     fSession = session;
  663.     // Cache tokenized focus names
  664.     fKeyFocusToken = fSession->Tokenize(ev, kODKeyFocus);
  665.     fMenuFocusToken = fSession->Tokenize(ev, kODMenuFocus);
  666.     fSelectionFocusToken = fSession->Tokenize(ev, kODSelectionFocus);
  667.     fModalFocusToken = fSession->Tokenize(ev, kODModalFocus);
  668.     fMouseFocusToken = fSession->Tokenize(ev, kODMouseFocus);
  669.     fScrollingFocusToken = fSession->Tokenize(ev, kODScrollingFocus);
  670.     
  671.     fLargeIconViewToken = fSession->Tokenize(ev, kODViewAsLargeIcon);
  672.     fSmallIconViewToken = fSession->Tokenize(ev, kODViewAsSmallIcon);
  673.     fThumbnailViewToken = fSession->Tokenize(ev, kODViewAsThumbnail);
  674.     
  675.     // Cache session globals for easy access
  676.     
  677.     fArbitrator = fSession->GetArbitrator(ev);
  678.     fWindowState = fSession->GetWindowState(ev);
  679.     fDispatcher = fSession->GetDispatcher(ev);
  680. }
  681.  
  682. //-------------------------------------------------------------------------------------
  683. // MacDispatchModule::Dispatch
  684. //
  685. // Description
  686. //-------------------------------------------------------------------------------------
  687.  
  688. ODBoolean MacDispatchModule::Dispatch(Environment* ev, ODEventData* event, ODEventInfo* eventInfo)
  689. {
  690.     ODEventType eventType = event->what;
  691.     
  692.     // Update cached object references to allow for patching (bug 1373276)
  693.     // $Opt: This could be improved if we knew when the patching phase has completed!
  694.     fArbitrator = fSession->GetArbitrator(ev);
  695.     fWindowState = fSession->GetWindowState(ev);
  696.     fDispatcher = fSession->GetDispatcher(ev);
  697.  
  698.     switch (eventType)
  699.     {
  700.         case nullEvent:
  701.             break;        // Currently handled in ODDispatcher
  702.             
  703.         case mouseDown:
  704.         case kODEvtBGMouseDown:
  705.             return this->DispatchMouseDownEvent(ev, event, eventInfo);
  706.             
  707.         case kODEvtMouseDownBorder:    // via Redispatch
  708.             return this->DispatchMouseDownInBorder(ev, event, eventInfo);     
  709.  
  710.         case kODEvtMouseDownEmbedded:
  711.         case kODEvtBGMouseDownEmbedded:
  712.             return this->DispatchMouseDownEmbedded(ev, event, eventInfo);     
  713.  
  714.         case kODEvtMouseUpEmbedded:
  715.             return this->DispatchMouseUpEmbedded(ev, event, eventInfo);     
  716.                     
  717.         case mouseUp:
  718.             return this->DispatchMouseUpEvent (ev, event, eventInfo);
  719.             
  720.         case keyDown:
  721.             return this->DispatchKeyDownEvent(ev, event, eventInfo);
  722.  
  723.         case autoKey:
  724.             return this->DispatchKeyDownEvent(ev, event, eventInfo);
  725.             
  726.         case keyUp:
  727.             return this->DispatchKeyUpEvent(ev, event, eventInfo);
  728.             
  729.         case updateEvt:
  730.             return this->DispatchUpdateEvent(ev, event);
  731.             
  732.         case activateEvt:
  733.             return this->DispatchActivateEvent(ev, event);
  734.             
  735.         case osEvt:
  736.             this->DispatchOSEvent(ev, event);
  737.             return kODTrue;
  738.     
  739.         case kHighLevelEvent:
  740.             break;    // Handled by shell
  741.                         
  742.         case kODEvtMenu:
  743.             return this->DispatchMenuEvent(ev, event, eventInfo);
  744.             
  745.         default:
  746.             return kODFalse;
  747.     }
  748.     return kODFalse;
  749. }
  750.  
  751. //-------------------------------------------------------------------------------------
  752. // MacDispatchModule::DispatchOSEvent
  753. // 
  754. // Description
  755. //-------------------------------------------------------------------------------------
  756.  
  757. void MacDispatchModule::DispatchOSEvent(Environment* ev, ODEventData* theEvent)
  758. {
  759.     unsigned char     typeOSEvent;
  760.     
  761.     // • Is it a multifinder event?
  762.     typeOSEvent = (unsigned char) ( theEvent->message >> 24 ) & 0x00FF;
  763.     
  764.     // • Switch on the type of OSEvent that occurred, high byte of message is event type
  765.     switch ( typeOSEvent ) 
  766.     {     
  767.         case kMouseMovedMessage:
  768.             this->MouseMoved(ev, theEvent);
  769.             break;
  770.             
  771.         case kSuspendResumeMessage:
  772.             this->SuspendResume(ev, theEvent);
  773.             break;
  774.     }
  775. }    
  776.  
  777. //-------------------------------------------------------------------------------------
  778. // MacDispatchModule::MouseMoved
  779. // 
  780. // Description
  781. //-------------------------------------------------------------------------------------
  782.  
  783. void MacDispatchModule::MouseMoved(Environment* ev, ODEventData* theEvent)
  784. {
  785.     ODUnused(theEvent);
  786.     
  787.     fDispatcher->InvalidateMouseRegion(ev);
  788. }
  789.  
  790. //-------------------------------------------------------------------------------------
  791. // MacDispatchModule::SuspendResume
  792. // 
  793. // Description
  794. //-------------------------------------------------------------------------------------
  795.  
  796. void MacDispatchModule::SuspendResume(Environment* ev, ODEventData* theEvent)
  797. {
  798.     fWindowState->SuspendResume(ev, theEvent);
  799.  
  800.     ODLinkManager* linkMgr = fSession->GetLinkManager(ev);
  801.     linkMgr->SuspendResume(ev, theEvent);
  802. }
  803.  
  804. //-------------------------------------------------------------------------------------
  805. // MacDispatchModule::DispatchMenuEvent
  806. // 
  807. // Description
  808. //-------------------------------------------------------------------------------------
  809.  
  810. ODBoolean MacDispatchModule::DispatchMenuEvent (Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  811. {
  812.     ODBoolean handled = kODFalse;
  813.  
  814.     long menuResult = theEvent->message;
  815.     short menu = HiWord(menuResult);
  816.     short item = LoWord(menuResult);
  817.  
  818.     TRY
  819.         
  820.     //if (menu != 0) // #
  821.     {
  822.         TempODFrame targetFrame = fArbitrator->AcquireFocusOwner(ev, fMenuFocusToken);
  823.         
  824. #if ODDebug && ODDebugMenuEvents
  825.     somPrintf("Menu Event %d, %d for frame %x\n",menu, item, (ODFrame*)targetFrame);
  826. #endif
  827.         
  828.         if ( targetFrame )
  829.         {
  830.             handled = this->DispatchTheEvent(ev, theEvent, targetFrame, kODNULL, eventInfo);
  831.         }
  832.         // Note: To support root menu items like Print. We could add a new focus for this
  833.         if (!handled)
  834.         {
  835.             TempODWindow window = fWindowState->AcquireActiveWindow(ev);
  836.             ODFrame* rootFrame = window ? window->GetRootFrame(ev) : kODNULL;
  837.             if (rootFrame && (rootFrame != targetFrame))
  838.             {
  839.                 TempODPart rootPart = rootFrame->AcquirePart(ev);
  840. #if ODDebug && ODLogEvents
  841.     LogEvent(theEvent, eventInfo, rootFrame, kODNULL);
  842. #endif
  843.                 handled = rootPart->HandleEvent(ev, theEvent, rootFrame, kODNULL, eventInfo);
  844.             }
  845.         }
  846.     }
  847.     //else
  848.     //    handled = kODTrue;
  849.     
  850.     CATCH_ALL
  851.         HiliteMenu(0);
  852.         RERAISE;
  853.     ENDTRY
  854.     
  855.     //if (handled)
  856.     HiliteMenu(0);
  857.  
  858.     return handled;
  859. }
  860.  
  861. //-------------------------------------------------------------------------------------
  862. // MacDispatchModule::DispatchMouseDownInContent
  863. // 
  864. // Description
  865. //-------------------------------------------------------------------------------------
  866.  
  867. ODBoolean MacDispatchModule::DispatchToFacetUnderPoint(Environment* ev, ODWindow* window, ODPoint& windowPt, 
  868.                                                     ODEventData* theEvent, ODEventInfo* eventInfo)
  869. {
  870.     ODBoolean handled = kODFalse;
  871.     
  872.     // Notes for bug 1330394
  873.     // ODWindow::GetFacetUnderPoint() skips child facets of a selected facet.  This is
  874.     // correct for mouse-down events, but not for mouse-up events that should activate
  875.     // a frame embedded in a selected facet.
  876.     // The fix is to call ODWindow::GetFacetUnderPointForDrag(), which does the same
  877.     // facet search but doesn't skip children of selected facets.  At a later, less
  878.     // heady date, we can change the method names to be GetFacetUnderPoint
  879.     // and GetFacetUnderPointNotSelected, or similar.
  880.     ODFacet* facet = kODNULL;
  881.     if ( theEvent->what == kODEvtMouseUp )
  882.         facet = window->GetFacetUnderPointForDrag(ev, &windowPt);
  883.     else
  884.         facet = window->GetFacetUnderPoint(ev, &windowPt);
  885.  
  886.     // If no facet was found, it's because the root facet's active shape must be smaller 
  887.     // than the frame shape. Send the event to the root facet anyway because it needs to
  888.     // do window activation, etc. Bug 1330894.
  889.     if ( facet == kODNULL )
  890.         facet = window->GetRootFacet(ev);
  891.  
  892.     ODFrame* frame = facet ? facet->GetFrame(ev) : kODNULL;
  893.  
  894.     if (facet && frame)
  895.     {
  896.         TempODFrame modalFocus = fArbitrator->AcquireFocusOwner(ev, fModalFocusToken);
  897.         if ( modalFocus && !IsContained(ev, frame, modalFocus))
  898.         {
  899.             TempODPart part = modalFocus->AcquirePart(ev); // -- TÇ tempobj'd
  900.             if (part)
  901.             {
  902. #if ODDebug && ODLogEvents
  903.     LogEvent(theEvent, eventInfo, modalFocus, kODNULL);
  904. #endif
  905.                 handled = part->HandleEvent(ev, theEvent, modalFocus, kODNULL, eventInfo);
  906.             }
  907.         }
  908.         else
  909.         {
  910.             ODTypeToken frameView = frame->GetViewType(ev);
  911.             ODBoolean isFrozen = frame->IsFrozen(ev);
  912.             ODBoolean isSelected = facet->IsSelected(ev);
  913.             ODBoolean isIcon = (frameView == fLargeIconViewToken ||
  914.                                 frameView == fSmallIconViewToken ||
  915.                                 frameView == fThumbnailViewToken);
  916.             ODBoolean isDragging = frame->IsDragging(ev);
  917.             ODBoolean isMouseDown = (theEvent->what != mouseUp);
  918.  
  919.             if ( isFrozen 
  920.                 || isSelected && isMouseDown
  921.                 || isIcon
  922.                 || isDragging && !isMouseDown)
  923.             {
  924.                 //PRINT("Mouse Down or Up to container\n");
  925.                 switch( theEvent->what ) 
  926.                 {
  927.                     case mouseDown:            theEvent->what = kODEvtMouseDownEmbedded; break;
  928.                     case kODEvtBGMouseDown:    theEvent->what = kODEvtBGMouseDownEmbedded; break;
  929.                     default:                theEvent->what = kODEvtMouseUpEmbedded; break;
  930.                 }
  931.                 eventInfo->embeddedFrame = frame;
  932.                 eventInfo->embeddedFacet = facet;
  933.                 
  934.                 ODFacet* containingFacet = kODNULL;
  935.                 containingFacet = facet->GetContainingFacet(ev);
  936.                 
  937.                 
  938.                 if ( containingFacet == kODNULL )
  939.                     handled = kODFalse;  // pass to shell/containerApp if this is a root frame
  940.                 else
  941.                 {
  942.                     // Cache the mouse down facet for use in mouse up dispatching, except
  943.                     // if the facet is selected, in which case the mouse up should go to the facet
  944.                     // under the mouse, provided the container doesn't do a drag.
  945.                     if ( isMouseDown )
  946.                     {
  947.                         if ( isFrozen || isIcon )
  948.                         {
  949.                             fMouseDownFacet = containingFacet;
  950.                             fEmbeddedFacet = facet;
  951.                         }
  952.                         else if ( isSelected )
  953.                         {
  954.                             // Get the actual facet under point, ignoring selection flag.
  955.                             // It's not the true mouse-down facet, but it is the one we want
  956.                             // the mouse-up to go to.
  957.                             fMouseDownFacet = window->GetFacetUnderPointForDrag(ev, &windowPt);
  958.                             fEmbeddedFacet = kODNULL;
  959.                         }
  960.                     }
  961.                     handled = fDispatcher->Redispatch(ev, theEvent, eventInfo);
  962.                 }
  963.             }
  964.             else
  965.             {
  966.                 fMouseDownFacet = facet;
  967.                 handled = this->DispatchTheEvent(ev, theEvent, frame, facet, eventInfo);
  968.             }
  969.         }
  970.     }
  971.     return handled;
  972. }
  973.  
  974. ODBoolean MacDispatchModule::DispatchMouseDownInContent (Environment* ev, ODWindow* theWindow,
  975.                                                                 ODEventData* theEvent, ODEventInfo* eventInfo)
  976. {
  977.     ODBoolean handled = kODFalse;
  978.     ODFacet* activeFacet = kODNULL;
  979.  
  980.     ODPoint windowPt; 
  981.     theWindow->GetWindowPoint(ev, &theEvent->where, &windowPt);
  982.     
  983.     ODBoolean modified = ((theEvent->modifiers & cmdKey) || (theEvent->modifiers & shiftKey)) != 0;
  984.     ODBoolean tooModified = ((theEvent->modifiers & optionKey) || (theEvent->modifiers & controlKey) ) != 0;
  985.     modified = modified && !tooModified;
  986.     eventInfo->where = windowPt;
  987.  
  988.     TempODFrame activeFrame = fArbitrator->AcquireFocusOwner(ev, fSelectionFocusToken); // -- TÇ tempobj'd
  989.     if ((ODFrame*)activeFrame ) 
  990.         activeFacet = GetActiveFacetWithBorderUnderPoint(ev, activeFrame, theWindow, ODPoint(windowPt));
  991.         
  992.     if ( activeFacet ) // Mouse down in border
  993.     {
  994.         if( theEvent->what==kODEvtBGMouseDown )
  995.             handled = kODFalse;
  996.         else
  997.         {
  998.             theEvent->what = kODEvtMouseDownBorder;
  999.             eventInfo->embeddedFrame = activeFrame;
  1000.             eventInfo->embeddedFacet = activeFacet;
  1001.             handled = fDispatcher->Redispatch(ev, theEvent, eventInfo);
  1002.         }
  1003.     }
  1004.     else // Click not in border
  1005.     {
  1006.         if (modified)
  1007.         {
  1008.             ODFacet* rootFacet = activeFrame ? GetActiveFacet(ev, activeFrame, theWindow, windowPt) 
  1009.                 : (ODFacet*) kODNULL;
  1010.             ODFacet* facet = GetFirstFacetUnderPoint(ev, theWindow, rootFacet, windowPt);
  1011.             // returns NULL, rootFacet or embeddedFrame
  1012.             
  1013.             if (facet)
  1014.             {
  1015.                 if (ODObjectsAreEqual(ev, facet, rootFacet))
  1016.                 {
  1017.                     fMouseDownFacet = rootFacet;
  1018.                     handled = this->DispatchTheEvent(ev, theEvent, activeFrame, rootFacet, eventInfo);
  1019.                 }
  1020.                 else // frame is embedded in active frame
  1021.                 {
  1022.                     theEvent->what = (theEvent->what==kODEvtBGMouseDown) ? kODEvtBGMouseDownEmbedded
  1023.                                                                          : kODEvtMouseDownEmbedded;
  1024.                     eventInfo->embeddedFrame = facet->GetFrame(ev);
  1025.                     eventInfo->embeddedFacet = facet;
  1026.                     fMouseDownFacet = rootFacet;
  1027.                     fEmbeddedFacet = facet;
  1028.                     //handled = this->DispatchTheEvent(ev, theEvent, activeFrame, rootFacet, eventInfo);
  1029.                     handled = fDispatcher->Redispatch(ev, theEvent, eventInfo);
  1030.                 }
  1031.             }    
  1032.             else if ( theWindow->IsFloating( ev ))    // Allow dispatch to floaters: #1337817
  1033.             {
  1034.                 // Assume that floating windows belong to the active part, so go ahead
  1035.                 // and dispatch.
  1036.                 handled = DispatchToFacetUnderPoint(ev, theWindow, windowPt, theEvent, eventInfo);
  1037.             }
  1038.             else    // Modified click outside active frame
  1039.             {
  1040.                 // Beep and eat the event
  1041.                 SysBeep(2);
  1042.                 fSuppressMouseUp = kODTrue;
  1043.                 handled = kODTrue;
  1044.             }
  1045.         }
  1046.         else // No modifiers
  1047.         {
  1048.             handled = DispatchToFacetUnderPoint(ev, theWindow, windowPt, theEvent, eventInfo);
  1049.         }
  1050.     }
  1051.     return handled;
  1052. } // MouseDownInContent
  1053.  
  1054. ODBoolean MacDispatchModule::DispatchMouseDownInBorder(Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  1055. {    
  1056.     ODBoolean handled = kODFalse;
  1057.     ODBoolean modified = ((theEvent->modifiers & cmdKey) || (theEvent->modifiers & shiftKey) ||
  1058.                           (theEvent->modifiers & optionKey) || (theEvent->modifiers & controlKey) ) != 0;
  1059.     
  1060.     if (modified)
  1061.     {
  1062.         SysBeep(2); // Shift-click or Command-click in border
  1063.         fSuppressMouseUp = kODTrue;
  1064.         handled = kODTrue;
  1065.     }
  1066.     else
  1067.     {    
  1068.         ODFacet* containingFacet = eventInfo->embeddedFacet->GetContainingFacet(ev);
  1069.         fMouseDownFacet = containingFacet;
  1070.         
  1071.         handled = this->DispatchTheEvent(ev, theEvent, containingFacet->GetFrame(ev), containingFacet, eventInfo);
  1072.     }
  1073.     return handled;
  1074. }
  1075.  
  1076. ODBoolean MacDispatchModule::DispatchMouseDownEmbedded(Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  1077. {    
  1078.     ODBoolean handled = kODFalse;
  1079.  
  1080.     ODFacet* containingFacet = eventInfo->embeddedFacet->GetContainingFacet(ev);
  1081.  
  1082.     // We don't cache mouse down facet here, because the mouse up goes to the embedded part in some cases
  1083.     
  1084.     handled = this->DispatchTheEvent(ev, theEvent, containingFacet->GetFrame(ev), containingFacet, eventInfo);
  1085.  
  1086.     return handled;
  1087. }
  1088.  
  1089. ODBoolean MacDispatchModule::DispatchMouseUpEmbedded(Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  1090. {    
  1091.     ODBoolean handled = kODFalse;
  1092.     
  1093.     if (fSuppressMouseUp)
  1094.     {
  1095.         handled = kODTrue;
  1096.     }
  1097.     else
  1098.     {
  1099.         if (    IsValidFacet( fMouseDownFacet ) 
  1100.              && IsValidFacet( fEmbeddedFacet ))
  1101.             handled = this->DispatchTheEvent(ev, 
  1102.                                 theEvent, 
  1103.                                 fMouseDownFacet->GetFrame(ev), 
  1104.                                 fMouseDownFacet, 
  1105.                                 eventInfo);
  1106.         else
  1107.             handled = kODTrue;
  1108.     }
  1109.  
  1110.     fMouseDownFacet = kODNULL;
  1111.     fEmbeddedFacet = kODNULL;
  1112.     return handled;
  1113. }
  1114.  
  1115. //-------------------------------------------------------------------------------------
  1116. // MacDispatchModule::DispatchMouseDownEvent
  1117. // 
  1118. // Description
  1119. //-------------------------------------------------------------------------------------
  1120.  
  1121. ODBoolean MacDispatchModule::DispatchMouseDownEvent (Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  1122. {
  1123.  
  1124.     ODBoolean handled = kODFalse;
  1125.  
  1126.     // Track the state of the mouse button
  1127.     fMouseButtonIsDown = kODTrue;
  1128.  
  1129.     TempODFrame mouseFocusFrame = fArbitrator->AcquireFocusOwner(ev, fMouseFocusToken); 
  1130.     if (mouseFocusFrame)
  1131.     {
  1132.         TempODPart part = mouseFocusFrame->AcquirePart(ev); 
  1133.         if ((ODPart*)part)
  1134.         {
  1135. #if ODDebug && ODLogEvents
  1136.     LogEvent(theEvent, eventInfo, mouseFocusFrame, fMouseDownFacet);
  1137. #endif
  1138.             handled = part->HandleEvent(ev, theEvent, mouseFocusFrame, fMouseDownFacet, eventInfo);
  1139.         }
  1140.     }
  1141.     else
  1142.     {
  1143.         WindowPtr platformWindow = kODNULL;
  1144.         TempODWindow aWindow = kODNULL;
  1145.         short         partCode;
  1146.         
  1147.         fMouseDownFacet = kODNULL;
  1148.         fEmbeddedFacet = kODNULL;
  1149.         fSuppressMouseUp = kODFalse;
  1150.         
  1151.         partCode = FindWindow ( theEvent->where, &platformWindow );
  1152.         
  1153.         if (platformWindow && fWindowState->IsODWindow(ev, platformWindow))
  1154.             aWindow = fWindowState->AcquireODWindow(ev, platformWindow);
  1155.         
  1156.         // Handle only clicks in OD content if this is a bg click:
  1157.         if( theEvent->what==kODEvtBGMouseDown )
  1158.         {
  1159.             fSuppressMouseUp = kODTrue;
  1160.             if( aWindow==kODNULL || partCode!=inContent )
  1161.                 return kODFalse;
  1162.         }
  1163.         if (partCode == inMenuBar)
  1164.         {
  1165.             // Check to see if we need to do "About OpenDoc..."
  1166.             ODBoolean overrideAboutCommand = ( theEvent->modifiers & optionKey ) != 0;
  1167.             if ( overrideAboutCommand )
  1168.                 overrideAboutCommand = SetupAboutOpenDocMenuText( ev, fWindowState );
  1169.             
  1170.             // Do the menu selection
  1171.             long menuResult = ::MenuSelect(theEvent->where);
  1172.             fMouseButtonIsDown = kODFalse;        // MenuSelect eats mouse-ups
  1173.  
  1174.             // Show OpenDoc's About Box if selected by user
  1175.             if ( overrideAboutCommand && ::IsAboutOpenDocEvent( ev, fWindowState, menuResult ))
  1176.             {
  1177.                 handled = kODTrue;
  1178.             }
  1179.             else if ( ::TSMMenuSelect(menuResult) )    // Handle TSM events
  1180.             {
  1181.                 handled = kODTrue;
  1182.             }
  1183.             else    // Let the part handle the menu command
  1184.             {
  1185.                 theEvent->what = kODEvtMenu;        
  1186.                 theEvent->message = menuResult;
  1187.                 handled = fDispatcher->Redispatch(ev, theEvent, eventInfo);
  1188.             }
  1189.         }
  1190.         else if (aWindow)
  1191.         {
  1192.             switch (partCode)
  1193.             {
  1194.                 case inContent:
  1195.                     handled = this->DispatchMouseDownInContent(ev, aWindow, theEvent, eventInfo);
  1196.                     break;
  1197.                     
  1198.                 case inGoAway:
  1199.                     if (TrackGoAway (platformWindow, theEvent->where))
  1200.                         handled = this->DispatchWindowEvent(ev, aWindow, partCode, theEvent, eventInfo);
  1201.                     else
  1202.                         handled = kODTrue;
  1203.                     break;
  1204.                     
  1205.                 case inDrag:
  1206.                     handled = this->DispatchWindowEvent(ev, aWindow, partCode, theEvent, eventInfo);
  1207.                     break;
  1208.  
  1209.                 case inGrow:
  1210.                     handled = this->DispatchWindowEvent(ev, aWindow, partCode, theEvent, eventInfo);
  1211.                     break;
  1212.                     
  1213.                 case inZoomIn:
  1214.                 case inZoomOut:
  1215.                     if (TrackBox(platformWindow, theEvent->where, partCode))
  1216.                         handled = this->DispatchWindowEvent(ev, aWindow, partCode, theEvent, eventInfo);
  1217.                     else
  1218.                         handled = kODTrue;
  1219.                     break;
  1220.                     
  1221.                 default:
  1222.                     break;
  1223.             }
  1224.         }
  1225.  
  1226.     }
  1227.  
  1228.     // If the mouse button has been released and there is no
  1229.     // mouseUp event waiting in the queue, assume it has been
  1230.     // consumed by the part and clear the mouse-down flag to
  1231.     // protect against pesky orphan mouse-ups that may follow.
  1232.     // First check to see if the mouse-down flag has already
  1233.     // been cleared (perhaps by reentrant calls to Dispatch,
  1234.     // see bug 1400043).
  1235.     if ( fMouseButtonIsDown )
  1236.     {
  1237.         EventRecord ignoreEvent;
  1238.         fMouseButtonIsDown = ::StillDown() || ::EventAvail( mUpMask, &ignoreEvent );
  1239.     }
  1240.  
  1241.     return handled;
  1242.  
  1243. }    //    MacDispatchModule::DispatchMouseDownEvent
  1244.  
  1245. //-------------------------------------------------------------------------------------
  1246. // MacDispatchModule::DispatchWindowEvent
  1247. // 
  1248. // Description
  1249. //-------------------------------------------------------------------------------------
  1250.  
  1251. ODBoolean MacDispatchModule::DispatchWindowEvent(Environment* ev, ODWindow* window, short partCode, 
  1252.                                                     ODEventData* theEvent, ODEventInfo* eventInfo)
  1253. {
  1254.     ODBoolean handled = kODFalse;
  1255.  
  1256.     TempODFrame modalFocus = fArbitrator->AcquireFocusOwner(ev, fModalFocusToken);
  1257.     if (modalFocus && !IsContained(ev, window->GetRootFrame(ev), modalFocus))
  1258.     {
  1259.         TempODPart part = modalFocus->AcquirePart(ev); // -- TÇ tempobj'd
  1260.         if ((ODPart*)part)
  1261.         {
  1262. #if ODDebug && ODLogEvents
  1263.     LogEvent(theEvent, eventInfo, modalFocus, kODNULL);
  1264. #endif
  1265.             handled = part->HandleEvent(ev, theEvent, modalFocus, kODNULL, eventInfo);
  1266.         }
  1267.     }
  1268.     else
  1269.     {
  1270.         ODFacet* rootFacet = window->GetRootFacet(ev);
  1271.         ODFrame* rootFrame = window->GetRootFrame(ev);
  1272.     
  1273.         theEvent->what = kODEvtWindow; 
  1274.         theEvent->message = partCode;
  1275. #if ODDebug && ODDebugTitleBarEvents
  1276.         somPrintf("Title Bar Event for root frame %x\n", rootFrame);
  1277. #endif
  1278.         handled = this->DispatchTheEvent(ev, theEvent, rootFrame, rootFacet, eventInfo);
  1279.     }
  1280.  
  1281.     // Window events are initiated by a mouse-down and processing them
  1282.     // consumes the mouse-up.  Even if the part didn't consume the 
  1283.     // mouse-up, as it should, we need to ignore it, so clear the
  1284.     // mouse-button-down flag.
  1285.     if ( handled ) 
  1286.         fMouseButtonIsDown = kODFalse;
  1287.  
  1288.     return handled;
  1289. }
  1290.  
  1291. //-------------------------------------------------------------------------------------
  1292. // MacDispatchModule::DispatchMouseUpEvent
  1293. // 
  1294. // Description
  1295. //-------------------------------------------------------------------------------------
  1296.  
  1297. ODBoolean MacDispatchModule::DispatchMouseUpEvent (Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  1298. {
  1299.     ODBoolean handled = kODFalse;
  1300.     WindowPtr platformWindow = kODNULL;
  1301.     TempODWindow aWindow = kODNULL;
  1302.     short         partCode;
  1303.     
  1304.     TempODFrame mouseFocusFrame = fArbitrator->AcquireFocusOwner(ev, fMouseFocusToken); 
  1305.  
  1306.     if ( !fMouseButtonIsDown )    // Was there a mouse-down preceeding this event?
  1307.     {
  1308.         // Bug 1382558: discard "orphan" mouse-up events
  1309.         ;  // Let the shell handle the event if it really wants to
  1310.     }
  1311.     else if ( fSuppressMouseUp )
  1312.     {
  1313.         handled = kODTrue;
  1314.     }
  1315.     else if (mouseFocusFrame)
  1316.     {
  1317.         TempODPart part = mouseFocusFrame->AcquirePart(ev); 
  1318.         if ((ODPart*)part)
  1319.         {
  1320. #if ODDebug && ODLogEvents
  1321.             LogEvent(theEvent, eventInfo, mouseFocusFrame, fMouseDownFacet);
  1322. #endif
  1323.             handled = part->HandleEvent(ev, theEvent, mouseFocusFrame, fMouseDownFacet, eventInfo);
  1324.         }
  1325.     }
  1326.     else
  1327.     {
  1328. #ifdef ODDebug    
  1329.         //somPrintf("Mouse Up\n");
  1330. #endif
  1331.  
  1332.         partCode = FindWindow ( theEvent->where, &platformWindow );
  1333.         ODBoolean modified = ((theEvent->modifiers & cmdKey) || (theEvent->modifiers & shiftKey)) != 0;
  1334.         ODBoolean tooModified = ((theEvent->modifiers & optionKey) || (theEvent->modifiers & controlKey) ) != 0;
  1335.         modified = modified && !tooModified;
  1336.         
  1337.         
  1338.         if (platformWindow)
  1339.             aWindow = fWindowState->AcquireODWindow(ev, platformWindow);
  1340.         
  1341.         if (aWindow)
  1342.         {
  1343.             ODPoint windowPt;
  1344.             aWindow->GetWindowPoint(ev, &theEvent->where, &windowPt);
  1345.             
  1346.             eventInfo->where = windowPt;
  1347.             
  1348.             switch ( partCode )
  1349.             {
  1350.                     case inContent:
  1351.                         // if (!modified)    // #1242893: What if it is?
  1352.                         {
  1353.                             // The new calls to IsValidFacet below make sure
  1354.                             // that the facet hasn't been deleted since it
  1355.                             // was cached.  This was happening when a window
  1356.                             // was being closed during mouse-down processing,
  1357.                             // causing the mouse-up to be sent to an invalid
  1358.                             // facet object.
  1359.                             if ( fMouseDownFacet == kODNULL )
  1360.                             {
  1361.                                 handled = DispatchToFacetUnderPoint(ev, 
  1362.                                                 aWindow, 
  1363.                                                 windowPt, 
  1364.                                                 theEvent, 
  1365.                                                 eventInfo);
  1366.                             }
  1367.                             else if ( IsValidFacet( fMouseDownFacet ))
  1368.                             {
  1369.                                 if ( fEmbeddedFacet == kODNULL )
  1370.                                 {
  1371.                                     handled = this->DispatchTheEvent(ev, 
  1372.                                                         theEvent, 
  1373.                                                         fMouseDownFacet->GetFrame(ev), 
  1374.                                                         fMouseDownFacet, 
  1375.                                                         eventInfo);                                
  1376.                                 }
  1377.                                 else if ( IsValidFacet( fEmbeddedFacet ))
  1378.                                 {
  1379.                                     theEvent->what = kODEvtMouseUpEmbedded;
  1380.                                     eventInfo->embeddedFacet = fEmbeddedFacet;
  1381.                                     eventInfo->embeddedFrame = fEmbeddedFacet->GetFrame(ev);
  1382.                                     handled = fDispatcher->Redispatch(ev, theEvent, eventInfo);
  1383.                                 }
  1384.                             }
  1385.                             // else ignore the event-- the cached mouse-down facet 
  1386.                             // has already been destroyed
  1387.                         }
  1388.                         break;
  1389.                     
  1390.                     default:
  1391.                         break;
  1392.             }
  1393.         }
  1394.     }
  1395.  
  1396.     fMouseDownFacet = kODNULL;
  1397.     fEmbeddedFacet = kODNULL;
  1398.     fMouseButtonIsDown = kODFalse;
  1399.     return handled;
  1400. }    //    MacDispatchModule::DispatchMouseUpEvent
  1401.  
  1402.  
  1403. //-------------------------------------------------------------------------------------
  1404. // MacDispatchModule::DispatchKeyDownEvent
  1405. // 
  1406. // Description
  1407. //-------------------------------------------------------------------------------------
  1408.  
  1409. ODBoolean MacDispatchModule::DispatchKeyDownEvent (Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  1410. {
  1411.     ODBoolean handled = kODFalse;
  1412.     const short kNotAllowed =  shiftKey | optionKey | controlKey;
  1413.     char key = (char) (theEvent->message & charCodeMask) ;
  1414.  
  1415.     FKeyResult F_KeyResult = ConvertKeyToFKeyMenuEvent( ev, theEvent,
  1416.             fWindowState );
  1417.  
  1418.     // if it's an F-key BUT is disabled, we have to drop it on the floor.  Parts
  1419.     // will not be expecting to get such menu events.  At the same time, they
  1420.     // should not be getting them as keydowns either, since they don't get anything
  1421.     // when users attempt to select dimmed menus.  So apart from sending the fake
  1422.     // menu event to tell parts to drop the clipboard focus we ignore this case.
  1423.     if ( F_KeyResult == kDisabledFKey )
  1424.     {
  1425.         FakeMenuEvent( ev, fDispatcher );
  1426.         handled = kODTrue;
  1427.     }
  1428.     else if ( F_KeyResult == kEnabledFKey ||
  1429.             ((theEvent->modifiers & cmdKey) && !(theEvent->modifiers & kNotAllowed)) )
  1430.     {
  1431.         long menuResult = F_KeyResult == kEnabledFKey ?
  1432.                 theEvent->message : MenuKey(key);
  1433.         short menu = HiWord(menuResult);
  1434.  
  1435.         if ( menu == 0 )     // Unmatched command keys, eg. Command-Period or Disabled Item
  1436.                             // Sent to part as keystroke
  1437.         {
  1438.             WASSERT( F_KeyResult == kNotAnFKey );        // shouldn't have gotten here that way
  1439.             // send a menuevent first so the part will relinquish the clipboard focus
  1440.             // as per the recipes.  Bug 1308137
  1441.             FakeMenuEvent( ev, fDispatcher );
  1442.  
  1443.             TempODFrame keyFrame = fArbitrator->AcquireFocusOwner(ev, fKeyFocusToken);
  1444.             handled = this->DispatchTheEvent(ev, theEvent, keyFrame, kODNULL, eventInfo);
  1445.         }
  1446.         else    // Turn it into a menu event
  1447.         {
  1448.             theEvent->what = kODEvtMenu;        
  1449.             theEvent->message = menuResult;        // in the fkey case, already set
  1450.             handled = fDispatcher->Redispatch(ev, theEvent, eventInfo);
  1451.  
  1452.             if (!handled)    // Deal with Close as a special case
  1453.             {
  1454.                 short item = LoWord(menuResult);
  1455.                 TempODMenuBar menuBar = fWindowState->AcquireCurrentMenuBar(ev);
  1456.                 ODCommandID command = menuBar ? menuBar->GetCommand(ev, menu, item) : 0;
  1457.                 
  1458.                 if (command == kODCommandClose)
  1459.                 {
  1460.                     TempODWindow activeWindow = fWindowState->AcquireActiveWindow(ev);
  1461.                     ODFrame* rootFrame = activeWindow ? activeWindow->GetRootFrame(ev) : kODNULL;
  1462.                     TempODPart rootPart = rootFrame ? rootFrame->AcquirePart(ev) : kODNULL;  // -- TÇ tempobj'd
  1463.                     
  1464.                     if (rootPart)
  1465.                     {
  1466. #if ODDebug && ODLogEvents
  1467.     LogEvent(theEvent, eventInfo, rootFrame, kODNULL);
  1468. #endif
  1469.                         handled = rootPart->HandleEvent(ev, theEvent,rootFrame, kODNULL, eventInfo);
  1470.                     }
  1471.                 }
  1472.             }
  1473.         }
  1474.     }
  1475.     else    // Regular unmodified keystrokes
  1476.     {
  1477.         TempODFrame scrollingFrame = fArbitrator->AcquireFocusOwner(ev, fScrollingFocusToken);
  1478.         if (scrollingFrame && 
  1479.             ((key == chPageUp) || (key == chPageDown) || (key == chHome) || (key == chEnd)))
  1480.         {
  1481.             handled = this->DispatchTheEvent(ev, theEvent, scrollingFrame, kODNULL, eventInfo);
  1482.         }    
  1483.         
  1484.         if (!handled)
  1485.         {
  1486.             TempODFrame keyFrame = fArbitrator->AcquireFocusOwner(ev, fKeyFocusToken);
  1487.             handled = this->DispatchTheEvent(ev, theEvent, keyFrame, kODNULL, eventInfo);
  1488.         }
  1489.     }
  1490.     return handled;
  1491. }    //    MacDispatchModule::DispatchKeyDownEvent
  1492.  
  1493. //-------------------------------------------------------------------------------------
  1494. // MacDispatchModule::DispatchKeyUpEvent
  1495. // 
  1496. // Description
  1497. //-------------------------------------------------------------------------------------
  1498.  
  1499. ODBoolean MacDispatchModule::DispatchKeyUpEvent (Environment* ev, ODEventData* theEvent, ODEventInfo* eventInfo)
  1500. {
  1501.     ODBoolean handled = kODFalse;
  1502.     {
  1503.         TempODFrame targetFrame = fArbitrator->AcquireFocusOwner(ev, fKeyFocusToken);
  1504.         handled = this->DispatchTheEvent(ev, theEvent, targetFrame, kODNULL, eventInfo);
  1505.     }    
  1506.     return handled;
  1507. }    
  1508.  
  1509. //-------------------------------------------------------------------------------------
  1510. // MacDispatchModule::DispatchUpdateEvent
  1511. // 
  1512. // Description
  1513. //-------------------------------------------------------------------------------------
  1514.  
  1515. ODBoolean MacDispatchModule::DispatchUpdateEvent (Environment* ev, ODEventData* theEvent)
  1516. {
  1517.     ODBoolean handled = kODFalse;
  1518.     
  1519.     WindowPtr platformWindow = (WindowPtr) theEvent->message;
  1520.     TempODWindow aWindow = kODNULL;
  1521.     
  1522.     if (platformWindow && fWindowState->IsODWindow(ev, platformWindow))
  1523.         aWindow = fWindowState->AcquireODWindow(ev, platformWindow);
  1524.     
  1525.     if ( aWindow )
  1526.     {
  1527.         aWindow->HandleUpdateEvent(ev, theEvent);
  1528.         handled = kODTrue;
  1529.     }
  1530.     return handled;
  1531. }    //    MacDispatchModule::DispatchUpdateEvent
  1532.  
  1533. //-------------------------------------------------------------------------------------
  1534. // MacDispatchModule::DispatchActivateEvent
  1535. // 
  1536. // Description
  1537. //-------------------------------------------------------------------------------------
  1538.  
  1539. ODBoolean MacDispatchModule::DispatchActivateEvent    (Environment* ev, ODEventData* theEvent)
  1540. {
  1541.     ODBoolean handled = kODFalse;
  1542.  
  1543.     WindowPtr platformWindow = (WindowPtr) theEvent->message;
  1544.     TempODWindow aWindow = kODNULL;
  1545.     
  1546.     if (platformWindow)
  1547.         aWindow = fWindowState->AcquireODWindow(ev, platformWindow);
  1548.  
  1549.     if (aWindow )
  1550.     {
  1551. #if ODDebug && ODDebugLayerEvents
  1552.     //if ( ((WindowPeek)platformWindow)->windowKind != dialogKind)
  1553.     //{ 
  1554.         if ((theEvent->modifiers & activeFlag) != 0)
  1555.             somPrintf("Ignoring Activate Event from event loop for root frame %x\n", aWindow->GetRootFrame(ev));
  1556.         else
  1557.             somPrintf("Ignoring Deactivate Event from event loop for root frame %x\n", aWindow->GetRootFrame(ev));
  1558.     //}
  1559. #endif
  1560.         // Note: Ignoring activate events solves the following problem:
  1561.         // When using the Drafts dialog to select an existing draft,
  1562.         // the dialog would generate an activate event for the window below it
  1563.         // when closed. The shell then opens the selected draft which brings its 
  1564.         // window to the front using ODWindow::Select (i.e. no events).
  1565.         // But then the activate event  comes in for the window which is no
  1566.         // longer frontmost.
  1567.  
  1568.         // Bit 1 (starting from 0) of the modifiers field is set in ODWindow::Activate/Deactivate 
  1569.         // to alert the dispatcher that this is an OpenDoc-generated activate event. Toolbox-generated
  1570.         // activates are ignored.
  1571.  
  1572.         if (IsODActivateEvent(*theEvent))
  1573.         {
  1574. #if ODDebug && ODDebugLayerEvents
  1575.         if ((theEvent->modifiers & activeFlag) != 0)
  1576.             somPrintf("OD Activate Event for root frame %x\n", aWindow->GetRootFrame(ev));
  1577.         else
  1578.             somPrintf("OD Deactivate Event for root frame %x\n", aWindow->GetRootFrame(ev));
  1579. #endif
  1580.             aWindow->HandleActivateEvent(ev, theEvent);
  1581.         }
  1582.         else
  1583.         {
  1584. #if ODDebug && ODDebugLayerEvents
  1585.         if ((theEvent->modifiers & activeFlag) != 0)
  1586.             somPrintf("MacOS Activate Event for root frame %x\n", aWindow->GetRootFrame(ev));
  1587.         else
  1588.             somPrintf("MacOS Deactivate Event for root frame %x\n", aWindow->GetRootFrame(ev));
  1589. #endif
  1590.         }
  1591.         
  1592.         handled = kODTrue;
  1593.     }
  1594.     return handled;    
  1595. }    //    MacDispatchModule::DispatchActivateEvent
  1596.  
  1597. //-------------------------------------------------------------------------------------
  1598. // MacDispatchModule::DispatchTheEvent
  1599. // 
  1600. // Dispatches the event to the initial target, or to a containing frame/facet,
  1601. // if the initial target doesn't handle it, and the containing part has
  1602. // set the "DoesPropagateEvents" flag of the embedded frame
  1603. //-------------------------------------------------------------------------------------
  1604.  
  1605. ODBoolean MacDispatchModule::DispatchTheEvent(Environment* ev, 
  1606.                             ODEventData* theEvent, 
  1607.                             ODFrame* targetFrame,
  1608.                             ODFacet* targetFacet,
  1609.                             ODEventInfo* eventInfo)
  1610. {
  1611.     ODBoolean handled = kODFalse;
  1612.     TempODPart targetPart = targetFrame ? targetFrame->AcquirePart(ev) : kODNULL; // -- TÇ tempobj'd
  1613.  
  1614.     if ((ODPart*)targetPart)
  1615.     {
  1616.         if (eventInfo && targetFacet)
  1617.             WindowToLocal(ev, eventInfo->where, targetFacet);
  1618. #if ODDebug && ODLogEvents
  1619.     LogEvent(theEvent, eventInfo, targetFrame, targetFacet);
  1620. #endif
  1621.         if (eventInfo && eventInfo->embeddedFrame)
  1622.         {
  1623.             handled = targetPart->HandleEvent(ev, theEvent, targetFrame, targetFacet, eventInfo);
  1624.         }
  1625.         else
  1626.             handled = targetPart->HandleEvent(ev, theEvent, targetFrame, targetFacet, eventInfo);
  1627.         if (!handled)
  1628.         {
  1629.             handled = PropagateTheEvent(ev, theEvent,targetFrame, targetFacet, eventInfo);
  1630.         }
  1631.     }
  1632.     return handled;
  1633. }
  1634.  
  1635. ODBoolean MacDispatchModule::PropagateTheEvent(Environment* ev, 
  1636.                             ODEventData* theEvent, 
  1637.                             ODFrame* initialFrame,
  1638.                             ODFacet* initialFacet,
  1639.                             ODEventInfo* eventInfo)
  1640. {    
  1641.     ODFacet* targetFacet = initialFacet;
  1642.     TempODFrame targetFrame = initialFacet ? initialFacet->GetFrame(ev) : initialFrame; // DMc refcount - temp
  1643.     // ODPart* targetPart = initialFrame ? initialFrame->AcquirePart(ev) : kODNULL; // Appears to be obsolete -TÇ
  1644.     ODBoolean handled = kODFalse;
  1645.         
  1646.     targetFrame->Acquire(ev);    // -- TÇ added
  1647.     while (targetFrame)
  1648.     {
  1649.         if (handled  || (!targetFrame->DoesPropagateEvents(ev)))
  1650.             break;
  1651.             
  1652.         if (targetFacet)
  1653.         {
  1654.             targetFacet = targetFacet->GetContainingFacet(ev);
  1655.             ODReleaseObject(ev, targetFrame); // DMc: about to reassign
  1656.             if ( targetFacet != kODNULL )
  1657.             {
  1658.                 targetFrame = targetFacet->GetFrame(ev);
  1659.                 targetFrame->Acquire(ev);
  1660.             }
  1661.             else
  1662.             {
  1663.                 targetFrame = kODNULL;
  1664.             }
  1665.         }
  1666.         else
  1667.         {
  1668.             ODFrame* contFrame = targetFrame->AcquireContainingFrame(ev);     // -- TÇ added
  1669.             ODReleaseObject(ev, targetFrame);                                // -- TÇ added
  1670.             targetFrame = contFrame;
  1671.         }
  1672.         
  1673.         {    
  1674.             TempODPart targetPart = targetFrame ? targetFrame->AcquirePart(ev) : kODNULL; // -- TÇ tempobj'd
  1675.             if ((ODPart*)targetPart)
  1676.             {
  1677.                 eventInfo->propagated = kODTrue;
  1678.                 handled = targetPart->HandleEvent(ev, theEvent, targetFrame, targetFacet, eventInfo);
  1679.             }
  1680.         }
  1681.     }
  1682.         
  1683.     return handled;
  1684. }
  1685.  
  1686.